var $ = window.$;
var sample = require('../../sample/manager');
var frac = require('../../../util/frac');
var layer = require('../../layer/manager');
var sound = require('../../audio/sound');
var timing = require('../../timing/manager');
var record = require('../../../core/record');
var util = require('../../../util/index');
var config = require('../../../core/config');
var vector = require('../vector');
var event = require('../../../core/event');

/**
 * 非独立模块, 作为ui的插件
 */
var GridEdit = function(){

};

GridEdit.prototype = {
	Intent_Add_Hold: 1,
	Intent_Add_Normal: 1 << 1,
	Intent_Rect_Select: 1 << 2,
	Intent_Change_Hold: 1<< 3,
	Intent_Drag: 1<< 4,
	Intent_Select: 1<< 5,
	Intent_Cancel_Select: 1<<6,
	Intent_Add_Catch_Hold : 1<<7,
	Intent_Add_Catch_Rain : 1<<8,

	setUI: function (_ui) {
		this.ui = _ui;
	},

	onMouseDown: function(pos, note, e){
		var _pos = this.ui.mouseToLayer(pos);
		var beat = this.ui.layerToGridOffset(_pos);
		var virtualNote = this.ui.paramToNote(beat);  //当前位置理论上的note

		if(beat[4] == -1){
			virtualNote = null;
		}

		this.data = {
			note: note,
			virtualNote: virtualNote,
			start: pos,
			startBeat: beat
		};
		if(note){
			if(e.shiftKey){
				this.intent = this.Intent_Change_Hold;
			}else{
				this.intent = this.Intent_Drag | this.Intent_Select;
			}
			this.data.div = this.ui.getNoteDiv(note.id);
		}else{
			//添加或框选, 先标记
			this.intent = this.Intent_Add_Normal | this.Intent_Rect_Select | this.Intent_Cancel_Select;
		}
	},

	onMouseMove: function (pos, e) {
		if(!this.data){
			return;
		}
		if(this.intent & this.Intent_Add_Hold){
			if(!this.data.note){
				if(!this.data.virtualNote){
					this.intent = 0;
					return;
				}
				//先新增一个note
				this.data.note = this.makeNewNote(this.data.virtualNote);
				this.data.div = this.ui.getNoteDiv(this.data.note.id);
				this.intent &= ~this.Intent_Add_Hold;
				this.intent |= this.Intent_Change_Hold;
			}
		}

		if(this.intent & this.Intent_Change_Hold){
			var note = this.data.note;
			var _pos = this.ui.mouseToLayer(pos);
			var _beat = this.ui.layerToGridOffset(_pos);
			_beat.pop();
			var cmp = frac.compare(_beat, note.beat);
			var endBeatOld = note.endbeat;
			if(cmp > 0){
				note.endbeat = _beat;
			}else{
				note.endbeat = note.beat;
			}
			//保证note在拖拽时至少有一个grid那么长
			var delta = frac.subtract(note.endbeat, note.beat);
			var minDelta = [0, 1, this.ui.divide];
			if(frac.compare(delta, minDelta) <= 0){
				note.endbeat = frac.add(note.beat, minDelta);
			}
			this.ui.alignNote(note, this.data.div);
		}

		if(this.intent & this.Intent_Drag){
			this.intent = this.Intent_Drag; //屏蔽掉其他可性能
			var beat = this.ui.mouseToGridOffset(pos);
			if(!this.data.currBeat){
				this.data.currBeat = this.data.startBeat;
			}
			if(!vector.equal(beat, this.data.currBeat)){
				//multiNote这里作为被拖动对象
				//如果当前note是选中的,那么拖动所有选中note
				//否则只拖动当前note
				if(!this.data.multiNote){
					if(this.data.div.hasClass('curr')){
						this.data.multiNote = this.ui.note.find('.curr');
					}else{
						this.data.multiNote = this.data.div;
					}
					this.data.multiArr = [];
					var divs = this.data.multiNote;
					for(var i=0;i<divs.size();i++){
						var obj = divs.eq(i);
						var offset = this.ui.getDivOffset(obj);
						this.data.multiArr.push(offset);
					}
				}

				var deltaY = this.ui.gridToLayerY(beat) - this.ui.gridToLayerY(this.data.currBeat);  //y差值
				var deltaX = (beat[3] - this.data.currBeat[3]) * this.ui._columnW;
				this.data.currBeat = beat;

				var divs = this.data.multiNote;
				var arr = this.data.multiArr;
				for(var i=0;i<divs.size();i++){
					var obj = divs.eq(i);
					arr[i].bottom += deltaY;
					arr[i].left += deltaX;
					obj.css({
						bottom: arr[i].bottom,
						left: arr[i].left
					});
				}
			}
		}

		if(this.intent & this.Intent_Rect_Select){
			if(this.intent != this.Intent_Rect_Select){
				//还没有判定为框选
				var move = vector.subAbs(pos, this.data.start);
				if(move[0] < 20 && move[1] < 20){
					return;
				}
			}

			this.intent = this.Intent_Rect_Select;  //排他
			if(!this.data.rectBeat){
				this.data.rectBeat = this.ui.mouseToGridUnsnap(this.data.start);
				this.ui.select.show();
			}
			var size = vector.subAbs(pos, this.data.start);
			var conf = {
				width: size[0],
				height: size[1]
			};
			if(pos[0] < this.data.start[0]){
				conf.left = pos[0];
			}else{
				conf.left = this.data.start[0];
			}
			conf.left += this.ui.offset[0];
			if(pos[1] < this.data.start[1]){
				conf.top = pos[1];
			}else{
				conf.top = this.data.start[1];
			}
			//conf.top += this.ui.offset[1];
			this.ui.select.css(conf);
		}
	},

	onMouseUp: function(pos, e){
		if(!this.data){
			return;
		}
		var move = vector.subAbs(pos, this.data.start);
		var noMove = move[0] < 6 && move[1] < 6;

		if((this.intent & this.Intent_Add_Hold)>0 && !this.data.note){
			//没有经过move事件, note是空, 退化为普通note
			this.intent &= ~this.Intent_Add_Hold;
			this.intent |= this.Intent_Add_Normal;
		}
		if((this.intent & this.Intent_Cancel_Select) > 0 && this.ui.getSelectCount() > 0){
			this.ui.cancelSelect();
			this.intent = 0;
		}
		if((this.intent & this.Intent_Add_Normal)>0 && !this.data.note && this.data.virtualNote){
			this.data.note = this.makeNewNote(this.data.virtualNote);
			this.data.div = this.ui.getNoteDiv(this.data.note.id);
			this.intent = 0;
			var time = this.adjustNoteSound(this.data.note);
			this.ui.checkMaxTime(time);
		}
		if((this.intent & this.Intent_Change_Hold) > 0 && this.data.note){
			var note = this.data.note;
			if(note.endbeat) {
				if (frac.compare(note.endbeat, note.beat) == 0) {
					delete note.endbeat;
				}
			}
		}

		if(this.intent & this.Intent_Select){
			if(e.ctrlKey){
				this.data.div.toggleClass('curr');
			}else{
				this.ui.cancelSelect();
				this.data.div.addClass('curr');
			}
			this.ui.pluginMeta.update();
			if(config.getVal(config.ITEM.PLAYSOUND)){
				this.ui.playNote(this.data.note);
			}
			this.intent = 0;
		}

		if((this.intent & this.Intent_Drag) > 0 && this.data.multiNote){
			var gridPos = this.ui.mouseToGridOffset(pos);
			var delta = frac.subtract(gridPos, this.data.startBeat);
			var deltaX = gridPos[3] - this.data.startBeat[3];
			//拖动模式的最后, 要移除编辑区域以外的note
			var divs = this.data.multiNote;
			var arr = this.data.multiArr;
			var needUpdate = false;
			for(var i =0;i<divs.size();i++){
				var obj = divs.eq(i);
				var offset = arr[i];

				if((offset.left >= this.ui._columnW * this.ui._columnCount) ||
					(offset.left + this.ui._columnW <= 0) ||
					(offset.bottom < 0)){
					this.ui.manager.removeNote(+obj.data('tag'));
					obj.remove();
					needUpdate = true;
					continue;
				}

				//最后修正note的grid值
				var note = this.ui.manager.getNote(+obj.data("tag"));
				note.beat = frac.add(note.beat, delta);
				if(note.endbeat){
					note.endbeat = frac.add(note.endbeat, delta);
				}
				if(note.column != undefined){
					note.column += deltaX;
				}

				var time = timing.beatToTime(note.beat) + (note.offset || 0);
				if (note.tid >= 0) {
					sound.offsetCell(note.tid, time);
				}
				this.ui.checkMaxTime(time);

			}
			if(needUpdate){
				this.ui.pluginMeta.update();
			}
			event.trigger(event.events.note.change);
		}

		if((this.intent & this.Intent_Rect_Select)>0 && this.data.rectBeat){
			this.ui.select.hide();
			//处理选中note
			var endGrid = this.ui.mouseToGridUnsnap(pos);
			var hasEdge = pos[0] < this.data.start[0]; //从右向左拉, 要包含跨边
			var _startY = this.ui.gridToLayerY(this.data.rectBeat);
			var _endY = this.ui.gridToLayerY(endGrid);
			//转换到左下 - 右上layer坐标
			//x可以用mouse值, 但y值必须从grid值转回layer值
			this.rectSelect([
				Math.min(this.ui.mouseStart[0], pos[0]),
				Math.min(_startY, _endY)
			],[
				Math.max(this.ui.mouseStart[0], pos[0]),
				Math.max(_startY, _endY)
			], hasEdge);
			this.ui.pluginMeta.update();
			this.intent = 0;
		}

		this.data = null;
	},

	makeNewNote: function(virtualNote){
		var _sound = sample.getCurrent();
		if(_sound){
			virtualNote.sound = _sound;
			//这里不要创建cell, 在up里集中处理
		}
		var _layer = layer.getCurrent();
		if(_layer != null){
			virtualNote.color = _layer;
		}
		this.ui.manager.addNote(virtualNote);
		this.addNoteDiv(virtualNote);
		this.ui.pluginUndo.mark("add_start");
		return virtualNote;
	},

	addNoteDiv : function(note){
        var noteDiv = $(this.ui.makeNoteDiv(note));
        noteDiv.appendTo(this.ui.note);
		this.ui.alignNote(note, noteDiv);
        return noteDiv;
	},

    adjustNoteSound : function(note){
		var time = timing.beatToTime(note.beat) + (note.offset || 0);
		if(note.sound && note.tid == -1){ // -1的初始值在manager load的时候刷新过一遍
            note.tid = sound.addCell(sample.getFilePath(note.sound), note.vol || 30, time);
		}
		return time;
    },

	rectSelect: function(leftBottom, rightTop, hasEdge){
		var notes = this.ui.note.find('div');
		var len = notes.size();
		for(var i=0;i<len;i++){
			var note = notes.eq(i);
			var rect = note[0].getBoundingClientRect();
			var left = parseInt(note.css('left'));
			var bottom = parseInt(note.css('bottom'));
			if(left + rect.width <= leftBottom[0]){
				continue;
			}else if(!hasEdge && left < leftBottom[0]){
				continue;
			}
			if(left >= rightTop[0]){
				continue;
			}else if(!hasEdge && left + rect.width > rightTop[0]){
				continue;
			}
			if(bottom + rect.height <= leftBottom[1]){
				continue;
			}else if(!hasEdge && bottom < leftBottom[1]){
				continue;
			}
			if(bottom >= rightTop[1]){
				continue;
			}else if(!hasEdge && bottom + rect.height > rightTop[1]){
				continue;
			}
			note.addClass('curr');
		}
	}

};

module.exports = GridEdit;